import {Component, useComponentsStore} from "../stores/components.tsx";
import React, {MouseEventHandler, useCallback, useEffect, useRef, useState} from "react";
import {useComponentConfigStore} from "../stores/component-config.tsx";
import HoverMask from "./HoverMask";
import SelectedMask from "./SelectedMask";

const EditArea = () => {
    const {components, currentComponentId, setCurrentComponent} = useComponentsStore();
    const {componentConfig} = useComponentConfigStore();
    const [hoverComponentId, setHoverComponentId] = useState<number>();
    const portalWrapperClassName = useRef(null)
    useEffect(() => {

    }, [])

    /**
     * 递归渲染组件
     * @param components 组件列表
     * @returns
     * */
    const renderComponents = useCallback((components: Component[]): React.ReactNode => {
        if (components.length === 0) return null;
            return components.map((component: Component) => {
                const config = componentConfig?.[component?.name]
                if (!config?.dev) {
                    return null;
                }

                if (config.materialType === "form") {
                    return React.createElement(
                        config.dev, // 一个组件或者一个html元素的字符串
                        {
                            key: component.id,
                            id: component.id,
                            name: component.name,
                            styles: component.styles ? component.styles : {...config.styles},
                            ...config.defaultProps,
                            ...component.props,
                            parentId: component?.parentId,
                        },
                        renderComponents(component.children || []) // 递归创建子组件
                    )
                }
                return React.createElement(
                    config.dev, // 一个组件或者一个html元素的字符串
                    {
                        key: component.id,
                        id: component.id,
                        name: component.name,
                        styles: component.styles ? component.styles : {...config.styles},
                        ...config.defaultProps,
                        ...component.props,
                        parentId: component?.parentId,

                    },
                    renderComponents(component.children || []) // 递归创建子组件
                )
            })
        }, [components]
    )
    /**
     * 鼠标移入组件事件处理
     * */
    const handleMouseOver = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
        // 获取当前元素的事件冒泡路径
        const path = e.nativeEvent.composedPath()
        for (let i = 0; i < path.length; i += 1) {
            const ele = path[i] as HTMLElement;
            // 获取自定义属性,自定义属性会将data-*属性转换为驼峰命名
            const componentId = ele.dataset?.componentId; // ele.dataset，是一个 dom 的属性，包含所有 data-xx 的属性的值：
            if (componentId) {
                setHoverComponentId(+componentId);
                return;
            }
        }
    }

    // 鼠标移出组件事件处理
    const handleMouseLeave = () => {
        setHoverComponentId(undefined)
    }

    /**
     * 点击组件事件处理
     * */
    const handleClick: MouseEventHandler = (e) => {
        // 获取当前元素的事件冒泡路径
        const path = e.nativeEvent.composedPath()
        for (let i = 0; i < path.length; i++) {
            const ele = path[i] as HTMLElement
            const componentId = ele.dataset?.componentId
            if (componentId) {
                setCurrentComponent(+componentId)
                return;
            }
        }
    }

    return (
        <div className={'w-[100%] h-[100%] edit-area'} onMouseOver={handleMouseOver} onMouseLeave={handleMouseLeave}
             onClick={handleClick}>
            {renderComponents(components)}
            {hoverComponentId && (
                // 鼠标移入组件时，显示一个遮罩层
                <HoverMask
                    portalWrapperClassName='portal-wrapper'
                    containerClassName='edit-area'
                    componentId={hoverComponentId}
                />
            )}
            {currentComponentId && (
                // 鼠标点击组件时，显示一个遮罩层
                <SelectedMask
                    portalWrapperClassName={portalWrapperClassName}
                    containerClassName='edit-area'
                    componentId={currentComponentId}
                />
            )}
            <div className="portal-wrapper" ref={portalWrapperClassName}></div>

        </div>
    )
};

export default EditArea;